package com.mezz.bones.framework.web.servlet;

import cn.hutool.core.util.StrUtil;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.util.Map;

@Slf4j
public class RepeatableHttpServletRequestWrapper extends HttpServletRequestWrapper {
  /**
   * 保存request body的数据
   */
  private String body;

  /**
   * 解析request的inputStream(即body)数据，转成字符串
   */
  public RepeatableHttpServletRequestWrapper(HttpServletRequest request) {
    super(request);
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = null;
    InputStream inputStream = null;

    // 若是表单请求,则直接从request.getParameterMap中获取
    if(StrUtil.containsAnyIgnoreCase(request.getContentType(),"application/x-www-form-urlencoded","form-data")){
      // 调用一次此方法 防止后续控制层request获取到的请求参数变空
      Map<String, String[]> parameterMap = request.getParameterMap();

      // 将参数缓存,以便后续构造curl请求参数时使用
      StringBuilder formData = new StringBuilder();
      for (String key : parameterMap.keySet()) {
        formData.append(" --data '").append(key).append("=").append(parameterMap.get(key)[0]).append("'");
      }
      this.body = formData.toString();
    } else {
      // json请求体获取
      try {
        inputStream = request.getInputStream();
        if (inputStream != null) {
          bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
          char[] charBuffer = new char[128];
          int bytesRead;
          while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
            stringBuilder.append(charBuffer, 0, bytesRead);
          }
        }
      } catch (IOException ex) {
        log.error("流读取失败 ",ex);
      } finally {
        if (inputStream != null) {
          try {
            inputStream.close();
          }
          catch (IOException e) {
            log.error("流关闭失败 ",e);
          }
        }
        if (bufferedReader != null) {
          try {
            bufferedReader.close();
          }
          catch (IOException e) {
            log.error("bufferedReader 关闭失败 ",e);
          }
        }
      }
      this.body = stringBuilder.toString();
    }
  }
  @Override
  public ServletInputStream getInputStream() {
    final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
    return new ServletInputStream() {
      @Override
      public boolean isFinished() {
        return false;
      }
      @Override
      public boolean isReady() {
        return false;
      }
      @Override
      public void setReadListener(ReadListener readListener) {
      }
      @Override
      public int read() {
        return byteArrayInputStream.read();
      }
    };
  }
  @Override
  public BufferedReader getReader() {
    return new BufferedReader(new InputStreamReader(this.getInputStream()));
  }
  public String getBody() {
    return this.body;
  }

  /**
   * 赋值给body字段
   */
  public void setBody(String body) {
    this.body = body;
  }
}
